package cn.kgc.spring.factory;

import cn.kgc.spring.annotatios.AutoWired;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.ResourceBundle;
import java.util.Set;

/**
 * @author 课工场
 * @date 2024/11/4
 * @description  实例工厂   创建对象
 * 设计一个通用方法 可以创建各种类型的实例对象   动态   反射
 */
public class BeanFactory {

    //  创建一个容器   存储实例化的对象
    private  static  final HashMap<String,Object> beans = new HashMap<>();

    static {
        // 读取配置文件  创建对象
        ResourceBundle bean = ResourceBundle.getBundle("bean");
        // 获取配置文件中所有的key
        Set<String> keys = bean.keySet();
        // 遍历key 获取所有的value  className  String
        keys.forEach(key->{
            String className = bean.getString(key);
            // 获取类对象
            try {
                Class<?> aClass = Class.forName(className);
                Constructor<?> declaredConstructor = aClass.getDeclaredConstructor();
                declaredConstructor.setAccessible(true);
                Object o = declaredConstructor.newInstance();
                // 将创建的对象存储在beans容器中
                beans.put(key,o);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

        });

        //  遍历 beans集合 完成对象属性初始化  @AutoWired
        beans.forEach((k,v)->{
            //  v  beans容器中的对象    动态解析   获取类对象
            Class<?> aClass = v.getClass();
            // 获取类对象中的属性
            Field[] declaredFields = aClass.getDeclaredFields();
            // 遍历属性
            for (Field declaredField : declaredFields) {
                // 判定属性上是否含有@AutoWired注解
                AutoWired annotation = declaredField.getAnnotation(AutoWired.class);
                if (annotation!=null){
                    // 赋值   根据属性名获取在beans中的对应对象  将获取的值赋值给当前属性
                    String fieldName= declaredField.getName();
                    Object o = beans.get(fieldName);
                    declaredField.setAccessible(true);
                    try {
                        declaredField.set(v,o);
                    } catch (IllegalAccessException e) {
                        throw new RuntimeException(e);
                    }

                }
            }
        });

    }


    // public static UserMapper getUserMapperImpl(){
    //
    //     return  new OracleMapperImpl();
    // }


    // public static  Object  getBean(Class clazz){
    //
    //     try {
    //         Constructor declaredConstructor = clazz.getDeclaredConstructor();
    //         Object o = declaredConstructor.newInstance();
    //         return  o;
    //     } catch (Exception e) {
    //         throw new RuntimeException(e);
    //     }
    //
    // }


    public static  <T> T  getBean(Class<T> clazz){

        try {
            Constructor declaredConstructor = clazz.getDeclaredConstructor();
            Object o = declaredConstructor.newInstance();
            return clazz.cast(o);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    public static  Object  getBean(String beanName){

        Object o = beans.get(beanName);

        return  o;
    }

    public static  <T> T  getBean(String beanName,Class<T> tClass){

        Object o = beans.get(beanName);
        return  tClass.cast(o);
    }

}
